package holdem.network;

import holdem.infengine.InferenceEngine;
import holdem.pokergui.PokerGUI;
import holdem.network.NetworkRequest.*;

//~--- imports: JDK -----------------------------------------------------------

import holdem.pokergui.MessageReceiverInGUI;
import java.io.*;

import java.net.Socket;


public class Client
{
    private Socket so;
    private ObjectInputStream streamIn;
    private ObjectOutputStream streamOut;
    PokerGUI m;
    InferenceEngine e;

    public Client(PokerGUI m) {
        this.m = m;
    }
    public Client(InferenceEngine e) {
        this.e = e;
    }

    //~--- methods ------------------------------------------------------------
    public void closeConnection() throws IOException {
        so.close();
    }

    public void initConnection(String strNode, int intPort) throws IOException {

        so = new Socket(strNode, intPort);

        System.out.println("Connecting...");

        streamIn = new ObjectInputStream(so.getInputStream());
        streamOut = new ObjectOutputStream(so.getOutputStream());
        if(this.e != null) {
            new InputStreamThread(e, streamIn);
        } else {
            new InputStreamThread(m, streamIn);
        }
    }

    private void sendMessage(NetworkRequest e) throws IOException
    {
        streamOut.writeObject(e);
    }

    public void bet(Integer amount) throws IOException
    {
        sendMessage(new BetRequest(amount));
    }

    public void raise(Integer amount) throws IOException
    {
        sendMessage(new RaiseRequest(amount));
    }

    public void fold() throws IOException
    {
        sendMessage(new FoldRequest());
    }

    public void check() throws IOException
    {
        sendMessage(new CheckRequest());
    }

    public void quit() throws IOException
    {
        sendMessage(new QuitRequest());
    }

    public void start() throws IOException
    {
        sendMessage(new StartRequest());
    }

    public void letMeJoin(String playerName, Integer money) throws IOException
    {
        sendMessage(new letMeJoinRequest(playerName, money));
    }
}

class InputStreamThread implements Runnable {

    Thread runner;
    MessageReceiverInGUI tmp;
    ObjectInputStream streamIn;

    public InputStreamThread(MessageReceiverInGUI tmp, ObjectInputStream streamIn) {
        runner = new Thread(this);
        this.tmp = tmp;
        this.streamIn = streamIn;
        runner.start();
    }

    public void run() {
        System.out.println(Thread.currentThread());
        while (true) {
            try {
                NetworkEvent cmd = (NetworkEvent) streamIn.readObject();
                cmd.event(tmp);
            } catch (IOException e) {
                break;
            } catch (ClassNotFoundException e) {
                throw new Error(e);
            }
        }

    }
}
